package main.newViz;

import framework.Game;

/**
 * Date: 15.05.2008
 * Time: 15:57:56
 *
 * @author Denis DIR Rozhnev
 *         <p/>
 *         todo use logger
 */
class Runner {
    private static final boolean VERBOSE = false;
    private static final StatisticsListener NULL_LISTENER = new StatisticsListener() {
        public void postIPS(int ips) {
            System.out.println("IPS: " + ips);
        }
    };
    private MyThread th;


    public Runner(Config config) {
        this(config.getGame());
        config.registerObserver(new Config.Observer() {
            public void configUpdate(Config config) {
                th.game = config.getGame();
            }
        });
    }

    public Runner(Game game) {
        th = new MyThread("Runner");
        th.setDaemon(true);
        th.game = game;
        th.start();
    }


    public void stop() {
        if (VERBOSE)
            System.out.println("Runner.stop()");
        th.turnToDo = 0;
    }

    public void start() {
        if (VERBOSE)
            System.out.println("Runner.start()");
        th.turnToDo = -1;
    }

    public void step(int turnCount) {
        if (VERBOSE)
            System.out.println("Runner.step()");
        th.turnToDo = turnCount;
    }

    public void setSleepAmount(long sleepAmount) {
        th.sleepAmount = sleepAmount;
    }

    public void setGame(Game game) {
        th.game = game;
    }

    private static class MyThread extends Thread {
        private boolean keepRuning = true;
        private long sleepAmount = 0;
        private int turnToDo = 0;
        private Game game;
        private StatisticsListener stat = NULL_LISTENER;

        public MyThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            int x = 0;
            long t0 = System.currentTimeMillis();
            while (keepRuning) {
                try {
                    if (turnToDo == 0) {
                        sleep(100);
                        x = 0;
                        t0 = System.currentTimeMillis();
                    } else {
                        game.turn(1);
                        x += 1;
                        if (x > 1000) {
                            long t = System.currentTimeMillis();
                            stat.postIPS((int) ((long) x * 1000 / (t - t0)));
                            x = 0;
                            t0 = t;
                        }
                        if (turnToDo > 0)
                            turnToDo--;
                        sleep(sleepAmount);
                        yield();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public interface StatisticsListener {
        /** Iteration per second */
        void postIPS(int ips);
    }
}
